/*
 * BPlusSimpleRegisterList.h
 *
 *  Created on: Oct 28, 2012
 *      Author: Federico Orquera
 */

#ifndef BPLUSSIMPLEREGISTERLIST_H_
#define BPLUSSIMPLEREGISTERLIST_H_

#include <memory>
#include "BPlusSimpleRegisterTemplate.h"

enum RegisterListResulExceptions {
	REGISTER_NOT_FOUND_IN_LIST
};


template <
	typename keyTemplate,
	typename valueTemplate,
	bool keyComparator(
		const keyTemplate& key1,
		const keyTemplate& key2
	)
>
class BPlusSimpleRegisterList {

public:

	typedef BPlusSimpleRegisterTemplate < keyTemplate, valueTemplate > 	registerType;
	typedef shared_ptr < registerType > 								register_ptr;
	typedef list< register_ptr > 										registerPointerList;
	typedef typename registerPointerList::iterator  					registerPointerListIterator;
	typedef shared_ptr<registerPointerList>  							registerPointerList_ptr;

	BPlusSimpleRegisterList() :
	    pRegisters( new registerPointerList() ){}

	BPlusSimpleRegisterList(
	   registerPointerList_ptr newList
	){
	    this->pRegisters = newList;
	}

	virtual ~BPlusSimpleRegisterList(){}

	registerPointerList& getList(){
		return (*pRegisters);
	}

	registerPointerListIterator& getIterator(){
		return it;
	}

	void simpleInsertRegister( const register_ptr& registro ){
		simpleInternalSearch( registro->getKey() );
		(this->pRegisters)->insert (it,registro);
	}

	void simpleUpdateRegister( const register_ptr& registro ){
		simpleInternalSearch( registro->getKey() );
		(this->pRegisters)->erase (it);
		(this->pRegisters)->insert (it,registro);
	}

	void simpleDeleteRegister( const keyTemplate& key ){
		simpleInternalSearch( key );
		if(it == (this->pRegisters)->end())throw RegisterListResulExceptions::REGISTER_NOT_FOUND_IN_LIST;
		(this->pRegisters)->erase (it);
	}

	registerPointerListIterator simpleInternalSearch( const keyTemplate& key ){
		for ( it=(this->pRegisters)->begin() ; (it != (this->pRegisters)->end() && keyComparator((*it)->getKey(), key) ) ; it++ );
		return it;
	}

	void setContent(const registerPointerList_ptr& registers) {
		pRegisters = registers;
	}

	// TODO: charlar esto con Fede!
	//const registerPointerList_ptr& getContent() const {
	registerPointerList_ptr& getContent() {
		return pRegisters;
	}

private:

	// Persistir.
	registerPointerList_ptr         pRegisters;

	// No persistir.
	registerPointerListIterator  	it;

};

#endif /* BPLUSSIMPLEREGISTERLIST_H_ */
